<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="生成时间">
        <el-date-picker
          v-model="queryParams.dateRange"
          type="daterange"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          value-format="yyyy-MM-dd">
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-s-promotion"
          size="mini"
          @click="handleBatchGenerate"
        >批量生成</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-delete-solid"
          size="mini"
          @click="handleCleanExpired"
        >清理过期文件</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="info"
          plain
          icon="el-icon-setting"
          size="mini"
          @click="handleShowConfig"
        >语音配置</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getVoiceFiles"></right-toolbar>
    </el-row>

    <!-- 语音文件统计卡片 -->
    <el-row :gutter="20" class="mb8">
      <el-col :span="6">
        <el-card shadow="hover" class="stats-card">
          <div class="stats-content">
            <div class="stats-icon">
              <i class="el-icon-folder-opened" style="color: #409eff;"></i>
            </div>
            <div class="stats-info">
              <div class="stats-number">{{ voiceStats.totalFiles }}</div>
              <div class="stats-label">总语音文件</div>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover" class="stats-card">
          <div class="stats-content">
            <div class="stats-icon">
              <i class="el-icon-time" style="color: #67c23a;"></i>
            </div>
            <div class="stats-info">
              <div class="stats-number">{{ voiceStats.todayFiles }}</div>
              <div class="stats-label">今日生成</div>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover" class="stats-card">
          <div class="stats-content">
            <div class="stats-icon">
              <i class="el-icon-pie-chart" style="color: #e6a23c;"></i>
            </div>
            <div class="stats-info">
              <div class="stats-number">{{ voiceStats.totalSize }}</div>
              <div class="stats-label">存储大小</div>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover" class="stats-card">
          <div class="stats-content">
            <div class="stats-icon">
              <i class="el-icon-warning" style="color: #f56c6c;"></i>
            </div>
            <div class="stats-info">
              <div class="stats-number">{{ voiceStats.expiredFiles }}</div>
              <div class="stats-label">过期文件</div>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <el-table v-loading="loading" :data="voiceFilesList">
      <el-table-column label="文件名" align="center" prop="fileName" width="200" show-overflow-tooltip />
      <el-table-column label="语音内容" align="center" prop="content" show-overflow-tooltip />
      <el-table-column label="播报类型" align="center" prop="type" width="100">
        <template slot-scope="scope">
          <el-tag size="small" :type="getTypeColor(scope.row.type)">
            {{ getTypeLabel(scope.row.type) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="语音参数" align="center" width="120">
        <template slot-scope="scope">
          <el-tooltip effect="dark" placement="top">
            <div slot="content">
              语音类型：{{ getVoiceTypeLabel(scope.row.voiceType) }}<br/>
              语速：{{ scope.row.speed }}<br/>
              音调：{{ scope.row.pitch }}<br/>
              音量：{{ scope.row.volume }}
            </div>
            <el-button type="text" size="mini" icon="el-icon-info">详情</el-button>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column label="文件大小" align="center" prop="fileSize" width="100">
        <template slot-scope="scope">
          {{ formatFileSize(scope.row.fileSize) }}
        </template>
      </el-table-column>
      <el-table-column label="生成时间" align="center" prop="createTime" width="150">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="播放" align="center" width="100">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-video-play"
            @click="playVoice(scope.row)"
            style="color: #67c23a;">
            播放
          </el-button>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" width="120">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-download"
            @click="downloadVoice(scope.row)"
          >下载</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            style="color: #f56c6c;"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getVoiceFiles"
    />

    <!-- 批量生成对话框 -->
    <el-dialog title="批量生成语音" :visible.sync="batchDialogVisible" width="700px" append-to-body>
      <div class="batch-generate-container">
        <el-form :model="batchForm" label-width="100px">
          <el-form-item label="生成方式">
            <el-radio-group v-model="batchForm.generateType">
              <el-radio label="stations">为所有站点生成</el-radio>
              <el-radio label="custom">自定义文本</el-radio>
            </el-radio-group>
          </el-form-item>

          <el-form-item label="播报类型" v-if="batchForm.generateType === 'stations'">
            <el-checkbox-group v-model="batchForm.announcementTypes">
              <el-checkbox label="arrival">到站播报</el-checkbox>
              <el-checkbox label="departure">发车播报</el-checkbox>
              <el-checkbox label="next">下一站播报</el-checkbox>
            </el-checkbox-group>
          </el-form-item>

          <el-form-item label="自定义文本" v-if="batchForm.generateType === 'custom'">
            <el-input
              v-model="batchForm.customTexts"
              type="textarea"
              :rows="6"
              placeholder="请输入要生成的文本，每行一条">
            </el-input>
          </el-form-item>

          <el-form-item label="语音参数">
            <el-row :gutter="20">
              <el-col :span="6">
                <label>语音类型：</label>
                <el-select v-model="batchForm.voiceType" size="small" style="width: 100%">
                  <el-option label="度小宇(男)" value="1"></el-option>
                  <el-option label="度小美(女)" value="0"></el-option>
                  <el-option label="度逍遥(男)" value="3"></el-option>
                  <el-option label="度丫丫(童)" value="4"></el-option>
                </el-select>
              </el-col>
              <el-col :span="6">
                <label>语速：</label>
                <el-slider v-model="batchForm.speed" :min="0" :max="15" size="small"></el-slider>
              </el-col>
              <el-col :span="6">
                <label>音调：</label>
                <el-slider v-model="batchForm.pitch" :min="0" :max="15" size="small"></el-slider>
              </el-col>
              <el-col :span="6">
                <label>音量：</label>
                <el-slider v-model="batchForm.volume" :min="0" :max="15" size="small"></el-slider>
              </el-col>
            </el-row>
          </el-form-item>
        </el-form>

        <!-- 批量生成进度 -->
        <div v-if="batchGenerating" class="batch-progress">
          <el-progress :percentage="batchProgress" :format="formatProgress"></el-progress>
          <p class="progress-text">{{ batchProgressText }}</p>
        </div>
      </div>

      <div slot="footer" class="dialog-footer">
        <el-button @click="startBatchGenerate" type="primary" :loading="batchGenerating">
          <i class="el-icon-s-promotion"></i> 开始生成
        </el-button>
        <el-button @click="batchDialogVisible = false" :disabled="batchGenerating">取消</el-button>
      </div>
    </el-dialog>

    <!-- 语音配置对话框 -->
    <el-dialog title="语音配置信息" :visible.sync="configDialogVisible" width="600px" append-to-body>
      <div class="config-container" v-if="voiceConfig">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="功能状态">
            <el-tag :type="voiceConfig.enabled ? 'success' : 'danger'">
              {{ voiceConfig.enabled ? '已启用' : '已禁用' }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="最大文本长度">
            {{ voiceConfig.maxTextLength }} 字节
          </el-descriptions-item>
        </el-descriptions>

        <el-divider content-position="left">支持的语音类型</el-divider>
        <el-table :data="voiceTypesList" size="small">
          <el-table-column prop="code" label="编码" width="80"></el-table-column>
          <el-table-column prop="name" label="语音类型"></el-table-column>
        </el-table>

        <el-divider content-position="left">参数范围</el-divider>
        <ul class="param-list">
          <li><strong>语速：</strong>{{ voiceConfig.speedRange }}</li>
          <li><strong>音调：</strong>{{ voiceConfig.pitchRange }}</li>
          <li><strong>音量：</strong>{{ voiceConfig.volumeRange }}</li>
        </ul>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getVoiceConfig, generateStationAnnouncement, cleanExpiredFiles } from "@/api/bus/tts"
import { listStations } from "@/api/bus/stations"
import {
  listVoiceFiles,
  getVoiceStatistics,
  delVoiceFile,
  cleanupExpiredFiles
} from "@/api/bus/voiceFiles"

export default {
  name: "VoiceManagement",
  data() {
    return {
      // 遮罩层
      loading: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 语音文件列表
      voiceFilesList: [],
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        dateRange: []
      },
      // 语音统计
      voiceStats: {
        totalFiles: 0,
        todayFiles: 0,
        totalSize: '0MB',
        expiredFiles: 0
      },
      // 批量生成
      batchDialogVisible: false,
      batchGenerating: false,
      batchProgress: 0,
      batchProgressText: '',
      batchForm: {
        generateType: 'stations',
        announcementTypes: ['arrival'],
        customTexts: '',
        voiceType: '1',
        speed: 5,
        pitch: 5,
        volume: 8
      },
      // 语音配置
      configDialogVisible: false,
      voiceConfig: null,
      voiceTypesList: []
    }
  },
  created() {
    this.getVoiceFiles()
    this.getVoiceStats()
  },
  methods: {
    /** 查询语音文件列表 */
    getVoiceFiles() {
      this.loading = true
      listVoiceFiles(this.queryParams).then(response => {
        this.voiceFilesList = response.rows.map(item => ({
          id: item.id,
          fileName: item.fileName,
          content: this.getAnnouncementText(item),
          type: this.mapAnnouncementTypeId(item.announcementTypeId),
          voiceType: item.voiceType || '1',
          voiceSpeed: item.voiceSpeed,
          voiceTone: item.voiceTone,
          fileSize: item.fileSize,
          duration: item.duration,
          stationId: item.stationId,
          createTime: new Date(item.createdAt).getTime()
        }))
        this.total = response.total
        this.loading = false
      }).catch(() => {
        this.loading = false
      })
    },
    /** 获取语音统计信息 */
    getVoiceStats() {
      getVoiceStatistics().then(response => {
        if (response.code === 200) {
          this.voiceStats = response.data
        }
      }).catch(() => {
        // 使用默认值
        this.voiceStats = {
          totalFiles: 0,
          todayFiles: 0,
          totalSize: '0MB',
          expiredFiles: 0
        }
      })
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getVoiceFiles()
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
        dateRange: []
      }
      this.handleQuery()
    },
    /** 批量生成 */
    handleBatchGenerate() {
      this.batchDialogVisible = true
    },
    /** 开始批量生成 */
    async startBatchGenerate() {
      this.batchGenerating = true
      this.batchProgress = 0

      try {
        if (this.batchForm.generateType === 'stations') {
          await this.generateStationVoices()
        } else {
          await this.generateCustomVoices()
        }
        this.$message.success('批量生成完成')
      } catch (error) {
        this.$message.error('批量生成失败: ' + error.message)
      } finally {
        this.batchGenerating = false
        this.batchDialogVisible = false
        this.getVoiceFiles()
      }
    },
    /** 生成站点语音 */
    async generateStationVoices() {
      // 获取所有站点
      const stationsRes = await listStations({ pageSize: 10000 })
      const stations = stationsRes.rows
      const types = this.batchForm.announcementTypes
      const totalTasks = stations.length * types.length

      let completed = 0
      for (const station of stations) {
        for (const type of types) {
          try {
            await this.generateSingleVoice(station.stationName, type)
            completed++
            this.batchProgress = Math.round((completed / totalTasks) * 100)
            this.batchProgressText = `正在生成：${station.stationName} - ${this.getTypeLabel(type)} (${completed}/${totalTasks})`
            await this.sleep(100) // 避免请求过快
          } catch (error) {
            console.error(`生成失败: ${station.stationName} - ${type}`, error)
          }
        }
      }
    },
    /** 生成自定义语音 */
    async generateCustomVoices() {
      const texts = this.batchForm.customTexts.split('\n').filter(text => text.trim())
      const totalTasks = texts.length

      let completed = 0
      for (const text of texts) {
        try {
          await this.generateCustomText(text.trim())
          completed++
          this.batchProgress = Math.round((completed / totalTasks) * 100)
          this.batchProgressText = `正在生成：${text.substring(0, 20)}... (${completed}/${totalTasks})`
          await this.sleep(100)
        } catch (error) {
          console.error(`生成失败: ${text}`, error)
        }
      }
    },
    /** 生成单个语音 */
    async generateSingleVoice(stationName, type) {
      return await this.$http.post('/dev-api/bus/tts/station', {
        stationName: stationName,
        announcementType: type
      })
    },
    /** 生成自定义文本语音 */
    async generateCustomText(text) {
      return await this.$http.post('/dev-api/bus/tts/generate', {
        text: text,
        voiceType: this.batchForm.voiceType,
        speed: this.batchForm.speed,
        pitch: this.batchForm.pitch,
        volume: this.batchForm.volume
      })
    },
    /** 清理过期文件 */
    async handleCleanExpired() {
      this.$confirm('确认清理7天前的过期语音文件?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        try {
          const response = await cleanupExpiredFiles(7)
          if (response.code === 200) {
            this.$message.success(response.msg)
            this.getVoiceFiles()
            this.getVoiceStats()
          }
        } catch (error) {
          this.$message.error('清理失败')
        }
      })
    },
    /** 显示语音配置 */
    async handleShowConfig() {
      try {
        const response = await getVoiceConfig()
        if (response.code === 200) {
          this.voiceConfig = response.data
          this.voiceTypesList = Object.entries(response.data.voiceTypes).map(([code, name]) => ({
            code: code,
            name: name
          }))
          this.configDialogVisible = true
        }
      } catch (error) {
        this.$message.error('获取配置失败')
      }
    },
    /** 播放语音 */
    playVoice(row) {
      const audio = new Audio(process.env.VUE_APP_BASE_API + '/voice/' + row.fileName)
      audio.play().catch(error => {
        console.error('播放失败:', error)
        this.$message.error('播放失败')
      })
    },
    /** 下载语音 */
    downloadVoice(row) {
      const link = document.createElement('a')
      link.href = process.env.VUE_APP_BASE_API + '/voice/' + row.fileName
      link.download = row.fileName
      link.click()
    },
    /** 删除语音文件 */
    handleDelete(row) {
      this.$confirm('确认删除该语音文件?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        try {
          const response = await delVoiceFile(row.id)
          if (response.code === 200) {
            this.$message.success('删除成功')
            this.getVoiceFiles()
            this.getVoiceStats()
          }
        } catch (error) {
          this.$message.error('删除失败')
        }
      })
    },
    /** 获取类型标签 */
    getTypeLabel(type) {
      const labels = {
        arrival: '到站',
        departure: '发车',
        next: '下一站'
      }
      return labels[type] || type
    },
    /** 获取类型颜色 */
    getTypeColor(type) {
      const colors = {
        arrival: 'success',
        departure: 'warning',
        next: 'primary'
      }
      return colors[type] || 'info'
    },
    /** 获取语音类型标签 */
    getVoiceTypeLabel(type) {
      const labels = {
        '1': '度小宇',
        '0': '度小美',
        '3': '度逍遥',
        '4': '度丫丫'
      }
      return labels[type] || type
    },
    /** 格式化文件大小 */
    formatFileSize(bytes) {
      if (bytes === 0) return '0 B'
      const k = 1024
      const sizes = ['B', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    },
    /** 格式化进度 */
    formatProgress(percentage) {
      return `${percentage}%`
    },
    /** 休眠函数 */
    sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms))
    },
    /** 根据报站类型ID映射到类型代码 */
    mapAnnouncementTypeId(typeId) {
      const mapping = {
        1: 'next',      // 即将到站
        2: 'arrival',   // 已到达
        3: 'transfer',  // 换乘提示
        4: 'terminal',  // 终点站
        5: 'safety'     // 安全提示
      }
      return mapping[typeId] || 'arrival'
    },
    /** 获取播报文本内容（基于类型和站点信息模拟） */
    getAnnouncementText(item) {
      const type = this.mapAnnouncementTypeId(item.announcementTypeId)
      const stationName = item.stationName || '未知站点'

      switch (type) {
        case 'arrival':
          return `列车即将到达${stationName}站，请准备下车`
        case 'departure':
          return `列车即将从${stationName}站发车，请注意安全`
        case 'next':
          return `下一站：${stationName}`
        case 'transfer':
          return `${stationName}站到了，可换乘其他线路`
        case 'terminal':
          return `终点站${stationName}到了，请带好随身物品下车`
        default:
          return `站点播报：${stationName}`
      }
    }
  }
}
</script>

<style scoped>
.stats-card {
  margin-bottom: 20px;
}

.stats-content {
  display: flex;
  align-items: center;
  padding: 10px;
}

.stats-icon {
  font-size: 40px;
  margin-right: 15px;
}

.stats-info {
  flex: 1;
}

.stats-number {
  font-size: 24px;
  font-weight: bold;
  color: #303133;
  line-height: 1;
}

.stats-label {
  font-size: 13px;
  color: #909399;
  margin-top: 5px;
}

.batch-generate-container {
  max-height: 60vh;
  overflow-y: auto;
}

.batch-progress {
  margin-top: 20px;
  padding: 20px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.progress-text {
  margin-top: 10px;
  font-size: 14px;
  color: #606266;
  text-align: center;
}

.config-container {
  max-height: 70vh;
  overflow-y: auto;
}

.param-list {
  padding-left: 0;
  list-style: none;
}

.param-list li {
  padding: 5px 0;
  color: #606266;
}
</style>